class DQNConfig:
    """通用DQN超参数配置"""
    def __init__(self):
        # 环境配置
        self.env_name = 'CartPole-v1'
        self.seed = 42

        # 网络配置
        self.state_dim = None  # 将在创建环境后设置
        self.action_dim = None  # 将在创建环境后设置
        self.hidden_dim = 128

        # 训练配置
        self.num_episodes = 1000
        self.batch_size = 32
        self.learning_rate = 1e-3
        self.gamma = 0.99

        # 梯度裁剪和数值稳定性
        self.grad_clip_norm = 1.0  # 梯度裁剪阈值
        self.use_huber_loss = True  # 使用Huber Loss替代MSE
        self.max_q_value = 50.0  # Q值裁剪上限
        self.weight_decay = 1e-5  # L2正则化

        # 探索配置
        self.epsilon_start = 1.0
        self.epsilon_end = 0.01
        self.epsilon_decay = 200

        # 学习率调度配置
        self.lr_schedule = 'step'  # 'step', 'exponential', 'cosine', None
        self.lr_step_size = 5000  # Step调度器：每多少步衰减一次
        self.lr_gamma = 0.5  # 衰减系数
        self.lr_update_freq = 100  # 多少训练步更新一次学习率
        self.lr_cosine_steps = 10000  # Cosine调度器的周期长度

        # 经验回放配置
        self.buffer_size = 10000
        self.min_buffer_size = 1000  # 开始训练前的最小缓冲区大小

        # 目标网络配置
        self.target_update_freq = 100  # 硬更新频率
        self.soft_target_update = False  # 是否使用软更新
        self.target_update_tau = 0.005  # 软更新系数

        # DQN变体配置
        self.double_dqn = True
        self.dueling_dqn = True
        self.prioritized_replay = True
        self.per_alpha = 0.6
        self.per_beta_start = 0.4
        self.per_beta_end = 1.0

        # 网络结构增强
        self.use_residual_connections = False  # 是否在网络中使用残差连接
        self.dropout_rate = 0.1  # Dropout比率，0表示不使用
        self.batch_norm = False  # 是否使用批标准化

        # Warm-up训练配置
        self.warmup_episodes = 200      # Warm-up训练的回合数
        self.warmup_lr_multiplier = 0.1 # Warm-up期间的学习率乘数

        # 高级训练策略
        self.use_n_step_returns = False  # 是否使用n步回报
        self.n_step = 3  # n步回报的步数
        self.use_noisy_networks = False  # 是否使用NoisyNet替代epsilon贪心

        # 自适应探索
        self.adaptive_epsilon = False  # 是否使用自适应epsilon
        self.epsilon_adapt_window = 500  # 自适应窗口大小
        self.epsilon_adapt_threshold = 0.02  # 胜率停滞阈值
        self.epsilon_boost_factor = 1.5  # epsilon提升系数

        # 高级PER配置
        self.advanced_per = False  # 是否使用高级优先级经验回放
        self.per_priority_strategy = 'td_error'  # PER优先级策略

        # 训练监控配置
        self.log_interval = 100
        self.save_interval = 200
        self.render = False
        self.monitor_training = True  # 是否监控训练统计
        self.print_training_stats_freq = 1000  # 打印训练统计的频率

        self.use_conv_network = False  # 是否使用全连接网络

    def set_advanced_features(self, **kwargs):
        """便捷方法：批量设置高级特性"""
        for key, value in kwargs.items():
            if hasattr(self, key):
                setattr(self, key, value)
            else:
                print(f"警告: 配置项 '{key}' 不存在")
        return self

    def get_architecture_summary(self):
        """获取网络架构摘要"""
        arch_info = {
            'dueling': self.dueling_dqn,
            'double_dqn': self.double_dqn,
            'residual': self.use_residual_connections,
            'noisy': self.use_noisy_networks,
            'dropout': self.dropout_rate,
            'hidden_dim': self.hidden_dim,
        }
        return arch_info

    def validate_config(self):
        """验证配置的合理性"""
        warnings = []

        # 检查epsilon参数
        if self.epsilon_start < self.epsilon_end:
            warnings.append("epsilon_start应该大于epsilon_end")

        # 检查学习率
        if self.learning_rate <= 0:
            warnings.append("学习率应该大于0")

        # 检查批次大小
        if self.batch_size > self.min_buffer_size:
            warnings.append("批次大小不应该大于最小缓冲区大小")

        # 检查高级特性兼容性
        if self.use_noisy_networks and self.adaptive_epsilon:
            warnings.append("NoisyNet和自适应epsilon同时启用可能冲突")

        # 检查PER设置
        if self.advanced_per and not self.prioritized_replay:
            warnings.append("高级PER需要先启用优先级回放")

        if warnings:
            print("⚠️ 配置验证警告:")
            for warning in warnings:
                print(f"   - {warning}")
        else:
            print("✅ 配置验证通过")

        return len(warnings) == 0

    def get_training_summary(self):
        """获取当前配置的训练摘要"""
        summary = f"""
        DQN配置摘要:
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━
        
        📊 基础参数:
           学习率: {self.learning_rate} (调度: {self.lr_schedule})
           批次大小: {self.batch_size}
           隐藏层维度: {self.hidden_dim}
           Gamma: {self.gamma}
        
        🛡️ 稳定性改进:
           梯度裁剪: {self.grad_clip_norm}
           Huber Loss: {self.use_huber_loss}
           Q值裁剪: {self.max_q_value}
           L2正则化: {self.weight_decay}
        
        🔍 探索策略:
           初始Epsilon: {self.epsilon_start}
           最终Epsilon: {self.epsilon_end}
           衰减步数: {self.epsilon_decay}
           自适应探索: {self.adaptive_epsilon}
           NoisyNet: {self.use_noisy_networks}
        
        🎯 目标网络:
           更新频率: {self.target_update_freq}
           软更新: {self.soft_target_update}
           软更新系数: {self.target_update_tau if self.soft_target_update else "N/A"}
        
        🧠 网络架构:
           Double DQN: {self.double_dqn}
           Dueling DQN: {self.dueling_dqn}
           残差连接: {self.use_residual_connections}
           Dropout: {self.dropout_rate}
        
        💾 经验回放:
           优先级回放: {self.prioritized_replay}
           高级PER: {self.advanced_per}
           PER策略: {self.per_priority_strategy if self.advanced_per else "标准"}
           Buffer大小: {self.buffer_size}
           最小训练大小: {self.min_buffer_size}
           N步回报: {self.use_n_step_returns}
        
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━
        """
        return summary.strip()